'''
Created on Aug 24, 2011

@author: david
'''
import os.path
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
import logging
import yaml

PSPYGEAR_YAML = "pspygear.yaml"
LINKAGE_ROOT_NODE = "ROOT"

class Server(object):
    
    def __init__(self,applets,debug=True):
        self._dispatchApplets= applets
        self._applets = {}
        self._debug = debug
        self._runLinkage(applets)
        
        logging.info("-- Server initialized")
        
    def _runLinkage(self,applets):
        """
        Arrange domain / subdomain 
        relationships
        """
        # parse applets into dict
        for ap in applets:
            k = ap[0].split('/')[1]
            self._applets[k] = ap[1]

        logging.debug("~~ Applets: %s" % str(self._applets))
                
        try:
            # load linkage from YAML
            # (may raise file not found
            if os.path.isfile(PSPYGEAR_YAML):
                f = open(PSPYGEAR_YAML)
                yml = yaml.load(f.read())
                f.close()
                lkg = yml['Linkage']
    
                # miss should trigger KeyError
                nodes = lkg[LINKAGE_ROOT_NODE] 
                self._setLinkage(nodes[0],lkg)
                
                logging.debug("~~ Linkage Set")
            else:
                logging.info("++ No linkage file found. no linkage set (%s)" % PSPYGEAR_YAML)                    
        except Exception, ex:
            logging.exception("!! Linkage Error, application linkage is unstable!")
    
    def _setLinkage(self,p,lkg):
        """
        set up parent / child domains
        """ 
        prnt = p
        if p == 'Default':
            for t in ['Default','.*','/','']:
                if self._applets.has_key(t):
                    prnt = t
                    break

        rh = self._applets[prnt]()
        
        nl = lkg[p]
        
        for n in nl:
            #logging("~~ Parent: %s  Child: %s" % (prnt,n))
            # check for recursion
            if lkg.has_key(n):
                self._setLinkage(n, lkg)
                
            # set domain linkage
            ch = self._applets[n]()
            rh.getDomain().addChild(ch.getDomain())
            logging.debug("~~ Added %s to %s" % (ch,rh))
            
    def getApp(self):
        """
        create and return a WSGI compliant app.
        
        -dkc-
        The GAE for Python 2.7 wants the raw web app.
        """
        return webapp.WSGIApplication(self._dispatchApplets)
    
    def run(self):
        # create web app from handler       
        wa = webapp.WSGIApplication(self._dispatchApplets,debug=self._debug)
    
        logging.info("-- starting server")
 
        # and run it
        run_wsgi_app(wa)
    
    